home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 …ember: Reference Library / Apple Developer Reference Library (December 1999) (Disk 1).iso / pc / technical documentation / macintosh technotes and q&as / technotes / tn / samplecode.sit.hqx / Sample Code / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-22  |  13.0 KB  |  406 lines

  1. /*
  2.     File:        main.c
  3.  
  4.     Contains:    This file is a shell that can be used to build QuickDraw GX applications.
  5.                 It contains all of the required calls to use the GX routines and QuickDraw
  6.                 together. It can put up one or more windows and also supports printing.
  7.  
  8.                 The application is expected to supply the following functions which are
  9.                 called by the shell:
  10.                     void  DoSetup(void);
  11.                     void  DoDraw(WindowPtr);
  12.                     OSErr DoNew(void);
  13.                     void  DoClose(WindowPtr);
  14.                     void  DoIdle(WindowPtr);
  15.                     void  DoTeardown(void);
  16.                     void  DoClick(WindowPtr, Point);
  17.  
  18.     Written by:    Developer Technical Support
  19.  
  20.     Copyright:    © 1992-1997 by Apple Computer, Inc., all rights reserved.
  21.  
  22.     Writers:
  23.  
  24.         (DMH)    Dave Hersey
  25.         (IK)    Ingrid Kelly
  26.  
  27.     Change History (most recent first):
  28.  
  29.          <2>      6/1/97    IK        Modified printing routines for GXGraphics 1.1.6.
  30.          <1>      9/1/92    DMH        First created.
  31. */
  32.  
  33. #include <CodeFragments.h>
  34. #include <Fonts.h>
  35. #include <Gestalt.h>
  36. #include <Resources.h>
  37.  
  38. #include "GraphicsLibraries.h"
  39. #include "PrintingLibrary.h"
  40.  
  41. #include "main.h"
  42.  
  43. /* ---------------------------------------------------------------------------
  44.     Global variables
  45.   --------------------------------------------------------------------------- */
  46.  
  47. short                 gAppResRefNum;
  48.  
  49. /*    gGraphicsHeapSize sets the size of the graphics gxHeap created by
  50.     calling the GXNewGraphicsClient routine. You can determine the amount of
  51.     graphics gxHeap required by using GraphicsBug.
  52. */
  53. long                gGraphicsHeapSize = 512;
  54.  
  55. gxGraphicsClient    gGXGraphicsClient;
  56.  
  57. /*    gOurPrintingOverrideUPP is a universal proc pointer for the printing
  58.     event override. This is so that the override can be native PowerPC code.
  59. */
  60. GXPrintingEventUPP    gGXPrintingEventUPP;
  61. GXFormatDialogUPP    gGXFormatDialogUPP;
  62.  
  63. Boolean                gQuitting = false;
  64. long                gSleep = 0;
  65.  
  66. #if defined(powerc) && !defined(__MWERKS__)
  67. QDGlobals        qd;
  68. #endif
  69.  
  70. /* ---------------------------------------------------------------------------
  71.     main
  72.   --------------------------------------------------------------------------- */
  73.  
  74. void main()
  75. {        
  76.     CursHandle            theCurs; 
  77.     Handle                menuBar;
  78.     WindowPtr            wind;
  79.  
  80.     gAppResRefNum = CurResFile();
  81.  
  82.     /*     Initialize the Mac OS Toolbox. */
  83.  
  84.     InitToolbox();
  85.  
  86.     theCurs = GetCursor(watchCursor);
  87.     SetCursor(*theCurs);
  88.  
  89.     /*     Create the menu bar. */
  90.  
  91.     menuBar = GetNewMBar(rMenuBar);
  92.     if ( menuBar == nil )
  93.         goto GetNewMBarFailed;
  94.  
  95.     SetMenuBar(menuBar);
  96.     DisposeHandle(menuBar);
  97.  
  98.     /*     Initialize the QuickDraw GX environment. */
  99.  
  100.     if ( !InitializeGXEnvironment() )
  101.     {
  102.         SetCursor(&qd.arrow);
  103.         (void)StopAlert(rNoQuickDrawGXALRTID, NULL);
  104.         return;
  105.     }
  106.  
  107.     /*    Before starting to draw, we'll call the DoSetup routine so we can
  108.         initialize any global variables or behaviors. This routine would be a good
  109.         time to change the gGraphicsHeapSize variable before we make the new
  110.         graphics client next.
  111.     */
  112.     DoSetup();
  113.  
  114.     /*     Initialize the other managers, if no errors occurred. */
  115.  
  116.     {
  117.         gQuitting = false;
  118.         AddResMenu(GetMHandle(mApple), 'DRVR'); /*  add Apple Menu items. */
  119.         DrawMenuBar();
  120.  
  121.         DoNew();
  122.         
  123.         SetCursor(&qd.arrow);  
  124.         
  125.         while (!gQuitting)
  126.             EventLoop();
  127.  
  128.         /*    Leaving. Close all the windows so we get rid of any data we or GX
  129.             created. Then, dispose of the common colors and exit the GX printing and
  130.             graphics environment.
  131.         */
  132.         while ( (wind = FrontWindow()) != NULL )
  133.             DoClose(wind);
  134.     }
  135.  
  136. GetNewMBarFailed:
  137.     TerminateGXEnvironment();    /*  Exit the QuickDraw GX environment. */
  138.     DoTeardown();                /*  Dispose of any global variables we made in DoSetup. */
  139. }
  140.  
  141. /* ---------------------------------------------------------------------------
  142.     InitToolbox
  143.   --------------------------------------------------------------------------- */
  144.  
  145. void InitToolbox (void)
  146. {
  147.     /*  Generic heap initialization. */
  148.     
  149.     MaxApplZone(); 
  150.     MoreMasters(); MoreMasters(); MoreMasters(); 
  151.     MoreMasters(); MoreMasters(); MoreMasters(); 
  152.     
  153.     /*  Start up the toolbox so we can notify people if there's a problem */
  154.     
  155.     InitGraf(&qd.thePort);
  156.     InitFonts();
  157.     InitWindows();
  158.     InitMenus();
  159.     TEInit();
  160.     InitDialogs(nil);
  161.     InitCursor();
  162. }
  163.  
  164. /* ---------------------------------------------------------------------------
  165.     InitializeGXEnvironment
  166.     Check to see if QuickDraw GX is installed. If not, alert the user...
  167.   --------------------------------------------------------------------------- */
  168.  
  169. Boolean InitializeGXEnvironment(void)
  170. {
  171.     long    theFeature;
  172.     Boolean    debuggingInitInstalled = false;
  173.  
  174.     /*    Before making any calls, check if QuickDraw GX is available. */
  175.  
  176.     if ( Gestalt(gestaltGraphicsVersion, &theFeature) != noErr )
  177.         return false;
  178.  
  179. #ifdef powerc
  180.     /*    This is a sanity check to see if the QuickDrawGXLib shared library is
  181.         installed. If the application is "weak" linked to the library, the
  182.         Process Manager will launch it even if the library is missing,
  183.         although the Code Fragment Manager will not resolve the addresses of
  184.         the functions in the library. If the application calls any of these
  185.         functions, it will crash.
  186.  
  187.         The application should check if any of the QuickDraw GX functions
  188.         cannot be resolved and exit gracefully if the library is missing. Note
  189.         that the check could be performed against any function the application
  190.         calls in the library. GXNewGraphicsClient is often the first function that
  191.         is called from the library, so it is convenient.
  192.     */
  193.     if ( (UInt32)GXNewGraphicsClient == kUnresolvedCFragSymbolAddress )
  194.         return false;
  195. #endif
  196.  
  197.     /*    The gestaltGraphicsAttr Gestalt attribute can be used to determine if the
  198.         GXGraphicsLib has been loaded, the GX debugging extension is
  199.         installed, or the PowerPC version version of GX is running. In our case,
  200.         we only need to know if the debugging extension was installed. If it is,
  201.         we will enable the GX validation and notice handling features. We define
  202.         debuggingInitInstalled as true to enable GX validation and notice handler
  203.         within the SetGXDebuggingWorld function.
  204.     */
  205.     if ( Gestalt(gestaltGraphicsAttr, &theFeature) == noErr )
  206.       if ( (theFeature & gestaltGraphicsIsDebugging) == gestaltGraphicsIsDebugging )
  207.          debuggingInitInstalled = true;
  208.  
  209.     /*    The GXNewGraphicsClient routine defines the graphics heap size. If you do
  210.         not make this call, the GX graphics engine will create this heap
  211.         automatically. How? It will create a heap which is a percentage of your
  212.         application's ideal memory foot print. This call allows you to explicity
  213.         define the ammount of memory used by the graphics system for its graphics
  214.         objects heap.
  215.     */
  216.     gGXGraphicsClient = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
  217.  
  218.     /*    After we attempted to create the graphics client, we need to determine if
  219.         the call succeeded. If the call did not (as in the case for all GX
  220.         functions), gGXGraphicsClient will be nil. If it is, we alert the user to
  221.         the problem. Otherwise, we will attempt to allocate the GX heap below.
  222.     */
  223.     if ( gGXGraphicsClient == nil )
  224.         return false;
  225.  
  226.     /* Initialize the new graphics environment and create the GX heap. */
  227.  
  228.     GXEnterGraphics();
  229.  
  230.     /*    Calling GXEnterGraphics allocates the memory within the GX heap. The only
  231.         reason the call would not succeed is if there is not enough memory. In
  232.         this case, the graphics error which will be posted is -27999 (out of
  233.         memory). At this point, we have not installed an error handler, so we
  234.         check for the error number corresponding to the out of memory error.
  235.     */
  236.     if ( GXGetGraphicsError(nil) != -27999 )
  237.     {
  238.         SetGXDebuggingWorld(debuggingInitInstalled);
  239.  
  240.         /*    Initialize the printing features within QuickDraw GX. */
  241.  
  242.         (void)GXPrInitPrinting();
  243.  
  244. #if 0
  245.         /*    Force the spooling functions of the PrintingLibrary to convert each
  246.             page shape to a QuickDraw picture before passing the compressed
  247.             QuickDraw GX data to QuickTime for decompression.
  248.         */
  249.         GXPrSetPrintingOptions(GXPrGetPrintingOptions() | kUseShapeToQuickDrawPictureConversion);
  250. #endif
  251.  
  252.         /*    Initialize the printing event override for the QuickDraw GX printing engine. */
  253.  
  254.         gGXPrintingEventUPP = NewGXPrintingEventProc(GXPrintingEventOverride);
  255.  
  256.         /*    Initialize the custom page format handler. */
  257.  
  258.         gGXFormatDialogUPP = NewGXFormatDialogProc(GXFormatDialogOverride);
  259.  
  260.         /*    We initialize the CommonColors Library. This will allow us to set the
  261.             color of a shape by calling the SetShapeCommonColor function. We will need
  262.             to call DisposeCommonColors when we leave, to clean up the world.
  263.         */
  264.         InitCommonColors();
  265.     }
  266.     else
  267.     {
  268.         /*    Since we can not allocate the requested size for our GX heap, we need to
  269.             throw away the client we created and alert the user that there is not
  270.             enough memory to continue.
  271.             
  272.             However, you could try to create a smaller GX heap. If you decide to try
  273.             to create a smaller GX heap which would meet the needs of your
  274.             application, you need to dispose of the client you had originally created.
  275.             Why? The original client contains the GX heap size requested, which was
  276.             too big, therefore you need to dispose of it and create a client
  277.             requesting a smaller size and call GXEnterGraphics and check for an error.
  278.         */
  279.         GXDisposeGraphicsClient(gGXGraphicsClient);
  280.         DebugStr ("\pInsufficient memory for QuickDraw GX.");
  281.     }
  282.  
  283.     return true;
  284. }
  285.  
  286. /* ---------------------------------------------------------------------------
  287.     TerminateGXEnvironment
  288.   --------------------------------------------------------------------------- */
  289.  
  290. void TerminateGXEnvironment(void)
  291. {
  292.     /*     Deallocate all of the default QuickDraw GX data structures. */
  293.  
  294.     DisposeCommonColors();
  295.  
  296.     DisposeRoutineDescriptor(gGXFormatDialogUPP);
  297.     DisposeRoutineDescriptor(gGXPrintingEventUPP);
  298.     GXPrExitPrinting();
  299.  
  300.     GXExitGraphics();
  301.     GXDisposeGraphicsClient(gGXGraphicsClient);
  302. }
  303.  
  304. /* ---------------------------------------------------------------------------
  305.     SetGXDebuggingWorld
  306.     This function enables the GX error handling capabilities and validation
  307.     routines. The validation routines are only enabled if the user has
  308.     installed the QuickDraw GX debugging extension. These routines are not
  309.     available with the non-debugging extension. Calling them when they are not
  310.     installed will not cause any problems, but it will cause unnecessary work
  311.     to be done by your application and the GX dispatcher.
  312.   --------------------------------------------------------------------------- */
  313.  
  314. void SetGXDebuggingWorld(Boolean debuggingInitInstalled)
  315. {
  316.     /*    Set QuickDraw GX validation routines if the user has installed the
  317.         QuickDraw GX debugging extension. gxPublicValidation will check parameters
  318.         to public routines. This validation setting is the recommended setting
  319.         while you are developing your GX application. For additional details
  320.         regarding the various levels of validation, see "Inside Macintosh:
  321.         QuickDraw GX Environment and Utilities." As you increase the amount of
  322.         validation, the drawing speed will SLOW down due to all of the internal
  323.         checking.
  324.     */
  325.     if ( debuggingInitInstalled )
  326.         GXSetValidation(gxPublicValidation + gxTypeValidation); 
  327.  
  328.     /*    Calling SetGraphicsLibraryErrors will install a GX error and warning
  329.         handler. This call is provided by the QuickDraw GX graphics debugging
  330.         library. Any time a GX error or warning is generated, it will be posted to
  331.         Macsbug.
  332.     */
  333.     SetGraphicsLibraryErrors();
  334.  
  335.     /*    If the user has installed the GX debugging version, we install a notice
  336.         handler. Why? The GX notice handling capabilities are only available with
  337.         the debugging version.
  338.     */
  339.     if ( debuggingInitInstalled )
  340.         SetGraphicsLibraryNotices();
  341. }
  342.  
  343. /* ---------------------------------------------------------------------------
  344.     GXPrintingEventOverride
  345.     Override for GXPrintingEvent. It allows us to update our windows when the
  346.     moveable modal printing dialogs are moved. Keep this in your main
  347.     segment, which will always be loaded when GX tries to call the routine.
  348.   --------------------------------------------------------------------------- */
  349.  
  350. OSErr GXPrintingEventOverride(EventRecord *event, Boolean filterEvent)
  351. {
  352.     if ( !filterEvent )
  353.         DoEvent(event);        /* generic event handler */
  354.  
  355.     return noErr;
  356. }
  357.  
  358. /* ---------------------------------------------------------------------------
  359.     GXFormatDialogOverride
  360.   --------------------------------------------------------------------------- */
  361.  
  362. OSErr GXFormatDialogOverride(gxFormat format, StringPtr title, gxDialogResult *result)
  363. {
  364.     Collection            formatCollection;
  365.     T_CustomCollection    customConfig;
  366.     gxPanelSetupRecord    panelInfo;
  367.     OSErr                error;
  368.  
  369.     if ( format == nil )
  370.         return paramErr;
  371.  
  372.     formatCollection = GXGetFormatCollection(format);
  373.     error = GXGetJobError(GXGetFormatJob(format));
  374.     if ( error != noErr )
  375.         goto GXGetFormatCollectionFailed;
  376.  
  377.     error = GetCollectionItem(formatCollection, kCustomCollectionType, gxPrintingTagID, nil, &customConfig);
  378.     if ( error == collectionItemNotFoundErr )
  379.     {
  380.         customConfig.one = false;
  381.         customConfig.two = false;
  382.         customConfig.three = 0;
  383.         
  384.         error = AddCollectionItem(formatCollection,
  385.                                   kCustomCollectionType,
  386.                                   gxPrintingTagID,
  387.                                   sizeof(T_CustomCollection),
  388.                                   &customConfig);
  389.     }
  390.  
  391.     if ( error == noErr )
  392.     {
  393.         panelInfo.panelKind = gxApplicationPanel;
  394.         panelInfo.panelResId = rFormatPanelDITLID;
  395.         panelInfo.resourceRefNum = gAppResRefNum;
  396.         panelInfo.refCon = 0;
  397.         
  398.         error = GXSetupDialogPanel(&panelInfo);
  399.     }
  400.  
  401. GXGetFormatCollectionFailed:
  402.     error = Forward_GXFormatDialog(format, title, result);
  403.  
  404.     return error;
  405. }
  406.